#include "compressedStream.cpp"
#include "Blocksort.cpp"

void crearBlockSort(bool debug = false){
	OBitFileManager* bitManager = new OBitFileManager("binary.dat");
	BlocksortCompress* bs = new BlocksortCompress();

	//bitManager->debug = debug;
	
	int blockSize = 8;
	string gamma = intToGamma( blockSize ); 
	if(debug) cout << endl << "BlockSize: " << blockSize << endl << "BlockSize Gamma: " << gamma << endl << endl;
	bitManager->writeBinaryString( &gamma );
	gamma.clear();
	
	string L;
	uInt I;
	
	if(debug) printf("Aplicando Blocksorting a 'PAPETAPE'...\n");
	bs->runBlock( "PAPETAPE" , &L, &I );
	gamma = intToGamma( I ); 
	if(debug) cout << "Blocksort result:\nI: " << I << "\nI (gamma): " << gamma << "\nL: " << L << endl << endl;

	bitManager->writeBinaryString( &gamma );
	bitManager->writeText( &L );
	
	L.clear();
	

	if(debug) printf("Aplicando Blocksorting a 'BLAHBLAH'...\n");
	bs->runBlock( "BLAHBLAH" , &L, &I );
	I++;
	gamma = intToGamma( I ); 
	if(debug) cout << "Blocksort result:\nI: " << I << "\nI (gamma): " << gamma << "\nL: " << L << endl << endl;
	
	bitManager->writeBinaryString( &gamma );
	bitManager->writeText( &L ); 
	
	L.clear();
	
	
	if(debug) printf("Aplicando Blocksorting a 'PAPETAPE'...\n");
	bs->runBlock( "PAPETAPE" , &L, &I );
	gamma = intToGamma( I ); 
	if(debug) cout << "Blocksort result:\nI: " << I << "\nI (gamma): " << gamma << "\nL: " << L << endl << endl;

	bitManager->writeBinaryString( &gamma );
	bitManager->writeText( &L );
	
	L.clear();
	

	if(debug) printf("Aplicando Blocksorting a 'BLAHBLAH'...\n");
	bs->runBlock( "BLAHBLAH" , &L, &I );
	I++;
	gamma = intToGamma( I ); 
	if(debug) cout << "Blocksort result:\nI: " << I << "\nI (gamma): " << gamma << "\nL: " << L << endl << endl;
	
	bitManager->writeBinaryString( &gamma );
	bitManager->writeText( &L ); 
	
	L.clear();



	if(debug) printf("Aplicando Blocksorting a 'TARJETA'...\n");
	bs->runBlock( "TARJETA" , &L, &I );

	gamma = intToGamma( I ); 
	if(debug) cout << "Blocksort result:\nI: " << I << "\nI (gamma): " << gamma << "\nL: " << L << endl << endl;
	bitManager->writeBinaryString( &gamma );
	bitManager->writeText( &L );

	L.clear();


	delete bs;
	delete bitManager;
}

void leerAllBits(bool debug=false){
	cout << "Leyendo de a 8 bits\n";
	IBitFileManager* bitManager = new IBitFileManager("binary.dat");
	uChar bit;
	uInt i = 1;
	while(true){
		if( ERROR_EOF == bitManager->getNextBit(&bit) ) break;
		cout << bit ;
		/*
		if( i % 8 == 0 ) 
			printf(" - "); 
		else if( i % 4 == 0 ) 
			printf(" "); 
		*/
		i++;
	}
	printf( "\n" );
	delete bitManager;
}

void leerBlockSort(bool debug=false){
	IBitFileManager* bitManager = new IBitFileManager("binary.dat");
	
	cout << endl << endl;
	string bits; string bytes; //uChar byte;
	
	bitManager->getNextBits(7,&bits);
	cout << "primeros 7 bits: '" << bits << "'" << endl; bits.clear();

	bitManager->getNextBits(3,&bits);
	cout << "siguientes 3 bits: '" << bits << "'" << endl; bits.clear();
	
	/*
	bitManager->getNextBits(8,&bits);
	cout << "siguientes 8 bits: '" << bits << "'" << endl; bits.clear(); // 01001100
	
	bitManager->getNextBits(8,&bits);
	cout << "siguientes 8 bits: '" << bits << "'" << endl; bits.clear(); // 01001100
	*/

	/*
	bitManager->getNextByte(&byte);
	cout << "siguiente byte: '" << byte << "'" << endl; 

	bitManager->getNextByte(&byte);
	cout << "siguiente byte: '" << byte << "'" << endl; 
	*/

	bitManager->getNextBytes(2,&bytes);
	cout << "siguientes 2 bytes: '" << bytes << "'" << endl; bytes.clear();

	delete bitManager;
}



int maintest(){
	
	cout << "Creando 'binary.dat'" << endl;
	crearBlockSort(1);
	
	//leerAllBits(); 
	//leerBlockSort();
		
	//cout << endl << endl << endl;
	cout << "Leyendo 'binary.dat'" << endl;
	ICompressedStream archivoComprimido("binary.dat");
	
	archivoComprimido.debug = true;
	
	
	string L;
	uInt I;
	string texto;
	bool is_eof = false;

	while(true){
		if( ERROR_EOF == archivoComprimido.readBlockSortingResult( &L , &I ) ){
			if( L.length() == 0 ) break;
			is_eof = true;
		}
		cout << endl;
		cout << "I: " << I << endl;
		cout << "L: " << L << endl;
		
		BlocksortDecompress::runBlock( L.c_str() , I , &texto );
		cout << "Texto original: '" << texto << "'" << endl;
		
		L.clear();
		if( is_eof ){
			cout << "EOF!"<< endl;
			return 0;
		}
	}
	


	return 0;
}

int main(){
	
	//maintest();
	/*
	OCompressedStream* archivoComprimido = new OCompressedStream("binary.dat",7);
	archivoComprimido->writeNumber(7);
	
	archivoComprimido->writeNumber(4);
	string text = "ABCDEFG";
	archivoComprimido->writeText(&text);
	
	archivoComprimido->writeNumber(9);
	text = "HIJKLMN";
	archivoComprimido->writeText(&text);
	
	delete archivoComprimido;
	*/
	
	ICompressedStream archivoComprimido2("binary.dat");
	uInt num; string L;
	/*
	archivoComprimido2.readNumber(&num); cout << "Num: " << num << endl;
	archivoComprimido2.readNumber(&num); cout << "Num: " << num << endl;
	*/
	archivoComprimido2.readBlockSortingResult(&L,&num); cout << "I: " << num << endl << "L: " << L << endl;
	archivoComprimido2.readBlockSortingResult(&L,&num); cout << "I: " << num << endl << "L: " << L << endl;
	
	return 0;
}
